package com.db.jdbc;

import com.db.jdbc.pool.DruidUtils;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * JDBC 操作工具类
 *
 * @author xin.ding
 * @date 2019/12/24 17:40
 */
public class JdbcTemplate {

    private JdbcTemplate() {
        throw new IllegalAccessError();
    }


    /**
     * DML 操作模板方法,自动创建数据库连接执行sql，执行完毕后自动关闭连接
     *
     * @param sql    执行操作的 SQL 语句
     * @param params SQL 语句参数
     */
    public static int update(String sql, Object... params) {

        try (
                Connection connection = DruidUtils.getConnection();
                PreparedStatement ps = connection.prepareStatement(sql)) {

            // 给预编译好的 sql 语句中的占位符进行赋值
            if (params != null && params.length > 0) {
                for (int i = 0; i < params.length; i++) {
                    ps.setObject(i + 1, params[i]);
                }
            }
            // 执行 SQL 语句
            return ps.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return 0;
    }


    /**
     * DML 操作模板方法 涉及事务时使用，需要传入数据库连接，并且使用后需手动关闭连接
     *
     * @param conn   数据库连接
     * @param sql    sql语句
     * @param params sql参数
     * @return 执行条数
     */
    public static int update(Connection conn, String sql, Object... params) {

        try (PreparedStatement ps = conn.prepareStatement(sql)) {
            if (params != null && params.length > 0) {
                for (int i = 0; i < params.length; i++) {
                    ps.setObject(i + 1, params[i]);
                }
            }
            return ps.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        }

        return 0;
    }

    /**
     * DQL 操作模板
     *
     * @param sql     执行操作的 SQL 语句
     * @param handler 对数据库返回结果集进行装箱的操作类
     * @param params  SQL 语句参数
     * @return 返回数据库查询结果集
     */
    public static <T> T query(String sql, ResultSetHandler<T> handler, Object... params) {

        try (
                Connection connection = DruidUtils.getConnection();
                PreparedStatement ps = connection.prepareStatement(sql);
                ResultSet rs = ps.executeQuery()) {

            if (params != null && params.length > 0) {
                for (int i = 0; i < params.length; i++) {
                    ps.setObject(i + 1, params[i]);
                }
            }
            // 调用处理结果集类对数据库查询结果集进行装箱
            return handler.handler(rs);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * DQL 操作模板 使用后需手动关闭连接
     *
     * @param connection Connection
     * @param sql        执行操作的 SQL 语句
     * @param handler    对数据库返回结果集进行装箱的操作类
     * @param params     SQL 语句参数
     * @return 返回数据库查询结果集
     */
    public static <T> T query(Connection connection, String sql, ResultSetHandler<T> handler, Object... params) {

        try (
                PreparedStatement ps = connection.prepareStatement(sql);
                ResultSet rs = ps.executeQuery()) {

            if (params != null && params.length > 0) {
                for (int i = 0; i < params.length; i++) {
                    ps.setObject(i + 1, params[i]);
                }
            }
            // 调用处理结果集类对数据库查询结果集进行装箱
            return handler.handler(rs);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

}
